package cn.edu.jxust.core.infrastructure.util;

import cn.hutool.core.bean.BeanUtil;
import lombok.extern.slf4j.Slf4j;
import java.lang.reflect.Constructor;
import java.util.ArrayList;
import java.util.List;

/**
 * @author QiuKangming
 * @version 1.0
 * @description 树形结构构建工具类
 * @since 2020/07/01 15:09
 */

@Slf4j
@SuppressWarnings("all")
public class BuildTreeUtils <K extends Cascadable, V, T> {

    /**
     * 构建泛型类构造器
     */
    private Constructor<K> kConstructor = null;
    private Constructor<V> vConstructor = null;
    private CascadeUtils<K> cascadeUtils = null;

    /**
     * 构造方法
     * @param kClass k
     * @param vClass v
     * @param tClass t
     * @throws Exception
     */
    public BuildTreeUtils(Class<K> kClass, Class<V> vClass, Class<T> tClass) throws Exception {
        try{
            kConstructor = kClass.getConstructor();
            vConstructor = vClass.getConstructor();
            cascadeUtils = new CascadeUtils<>();
        }catch (Exception e){
            log.error("BuildTreeUtils --> 构造方法: " + e.getMessage());
        }

    }

    /**
     * 将 源对象 对象转换成 源视图 对象
     * @param src 源对象
     * @return List<V>
     */
    public List<V> buildVo(List<T> src){
        if(null == src || src.size() == 0){
            return null;
        }
        //将 Source 对象 转换成 SourceBuild 对象
        List<K> srcBuilds = new ArrayList<>(src.size());
        src.forEach(s -> {
            K k = null;
            try {
                k = kConstructor.newInstance();
            } catch (Exception e) {
                log.error("BuildTreeUtils --> [buildVo]: " + e.getMessage());
            }
            assert k != null;
            BeanUtil.copyProperties(s, k);
            srcBuilds.add(k);
        });

        //treeMenu 已经是分好级的菜单
        List<K> treeSourceBuild = cascadeUtils.formatCascadeTree(srcBuilds);
        List<V> treeSourceVo = new ArrayList<>();
        treeSourceBuild.forEach(treeItem -> {
            V v = null;
            try {
                v = vConstructor.newInstance();
            } catch (Exception e) {
                e.printStackTrace();
            }
            assert v != null;
            BeanUtil.copyProperties(treeItem, v);
            treeSourceVo.add(v);
        });
        return treeSourceVo;
    }
}
